package com.fary.nio;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class NioBufferDemo {
    public static void main(String[] args) {
        try {
            testWrite();
            testRead();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private static void testWrite() throws IOException {
        FileOutputStream fos = new FileOutputStream("testNIO.txt");
        FileChannel channel = fos.getChannel();
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        for (int i = 0; i < 10; i++) {
            byteBuffer.put((byte) i);
            System.out.println("write : " + (byte) i);
        }
        byteBuffer.flip();
        channel.write(byteBuffer);

        fos.close();

    }

    private static void testRead() throws IOException {
        FileInputStream fis = new FileInputStream("testNIO.txt");
        FileChannel fileChannel = fis.getChannel();
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        while (true) {
            int n = fileChannel.read(byteBuffer);
            System.out.println("read..." + n);
            if (n == -1) {
                break;
            }
        }
        byteBuffer.flip();

        while (byteBuffer.hasRemaining()) {
            System.out.println("read : " + byteBuffer.get());
        }

        fis.close();
    }

    private static void testCopyFile() throws IOException {
        FileInputStream fis = new FileInputStream("testNIO.txt");
        FileOutputStream fos = new FileOutputStream("testNIOCopy.txt");
        FileChannel inChannel = fis.getChannel();
        FileChannel outChannel = fos.getChannel();
        // 此时position=0,limit=capacity
        ByteBuffer byteBuffer = ByteBuffer.allocate(3);
        while (true) {
            // read前，position=0，limit=3
            int n = inChannel.read(byteBuffer);
            // read后，position=3，limit=3
            System.out.println("n = " + n);
            if (n == -1) {
                break;
            }
            // flip后，position=0，limit=3，经过3次之后，position=0,limit=1,因为这次只读1个元素
            byteBuffer.flip();
            outChannel.write(byteBuffer);
            // clear()把position=0, limit=3;方便下一次读取使用buffer
            byteBuffer.clear();
        }

        // 除了用上面的方式外，还有一个更快捷的方法：transferTo,transferFrom
        inChannel.transferTo(0, inChannel.size(), outChannel);
        // 或者是
        outChannel.transferFrom(inChannel, 0, inChannel.size());

    }

    // 分片,与原来的buffer共享数据
    private static void testslice() {
        ByteBuffer byteBuffer = ByteBuffer.allocate(6);
        for (int i = 1; i <= 6; i++) {
            byteBuffer.put((byte) i);
        }

        byteBuffer.clear();
        while (byteBuffer.hasRemaining()) {
            System.out.println(byteBuffer.get());
        }

        System.out.println("----------");

        // 取数组的第3个和第4个元素，limit指向的是最后一个元素的下一个
        byteBuffer.position(2);
        byteBuffer.limit(4);
        ByteBuffer slice = byteBuffer.slice();
        for (int i = 0; i < slice.capacity(); i++) {
            // 这里的get是绝对的，不影响position的值
            slice.put((byte) (slice.get(i)*10));
        }

        byteBuffer.clear();
        while (byteBuffer.hasRemaining()) {
            System.out.println(byteBuffer.get());
        }
    }
}